//Includes
#include "esos.h"
#include "esos_pic24.h"
#include "esos_pic24_rs232.h"

//Hardware config macros
#define CONFIG_LED1() CONFIG_RB15_AS_DIG_OUTPUT()
#define LED1 _LATB15
#define CONFIG_LM60() CONFIG_AN1_AS_ANALOG()
#define CONFIG_VREF() CONFIG_AN0_AS_ANALOG()

//Software macros
#define TEMP_BUFFER_SIZE 7
#define TEMP_BUFFER_MEDIAN 3
#define VREF 0x3000
#define RESOLUTION 4096
#define INIT_MIN_TEMP 4096
#define INIT_MAX_TEMP 0
#define BUFFER_INIT ESOS_USER_FLAG_0
#define EIGHT_BYTES 8
#define EIGHT_BYTE_FILTER 0xFF
#define HALF_SECOND 500
#define QUARTER_SECOND 250

//Global variables
static uint16 u16_minTemp;
static uint16 u16_maxTemp;
static uint16 au16_orderTempArray[TEMP_BUFFER_SIZE];
static uint16 au16_filterTempArray[TEMP_BUFFER_SIZE];
static uint8  u8_arrayIndex;


//Heartbeat LED task - blinks LED1 every 250ms
ESOS_USER_TASK(heartbeat_LED)
{
	ESOS_TASK_BEGIN();
	while (TRUE)
	{
		LED1 = !LED1;
		ESOS_TASK_WAIT_TICKS(250);
	}
	ESOS_TASK_END();
}

ESOS_USER_TASK(bt_COMM)
{
    static uint8 u8_char[3];
    static uint8 u8_lastChar;
    static uint8 *pu8_char = u8_char;
    static uint8 u8_bufferCharCount = 0;
    ESOS_TASK_BEGIN();
    ESOS_TASK_WAIT_ON_AVAILABLE_OUT_COMM();
    ESOS_TASK_WAIT_ON_AVAILABLE_IN_COMM();
    do
    {
    ESOS_TASK_WAIT_TICKS(500);
    ESOS_TASK_WAIT_ON_SEND_STRING("$$$\n");
    if (IS_ESOS_COMM_GOT_IN_DATA())
    {
        ESOS_TASK_WAIT_ON_GET_STRING(u8_char);
    }
    u8_lastChar = u8_char[0];
    } while (u8_char[0] != 'C');
    FLUSH_ESOS_COMM_IN_DATA();
    do
    {
    ESOS_TASK_WAIT_TICKS(500);
    ESOS_TASK_WAIT_ON_SEND_STRING("SN,AndroMeter\n");
    if (IS_ESOS_COMM_GOT_IN_DATA())
    {
        ESOS_TASK_WAIT_ON_GET_STRING(u8_char);
    }
    u8_lastChar = u8_char[0];
    } while (u8_char[0] != 'A');
    FLUSH_ESOS_COMM_IN_DATA();
    do
    {
    ESOS_TASK_WAIT_TICKS(500);
    ESOS_TASK_WAIT_ON_SEND_STRING("SM,0\n");
    if (IS_ESOS_COMM_GOT_IN_DATA())
    {
        ESOS_TASK_WAIT_ON_GET_STRING(u8_char);
    }
    u8_lastChar = u8_char[0];
    } while (u8_char[0] != 'A');
    FLUSH_ESOS_COMM_IN_DATA();
    do
    {
    ESOS_TASK_WAIT_TICKS(500);
    ESOS_TASK_WAIT_ON_SEND_STRING("SO,Slave\n");
    if (IS_ESOS_COMM_GOT_IN_DATA())
    {
        ESOS_TASK_WAIT_ON_GET_STRING(u8_char);
    }
    u8_lastChar = u8_char[0];
    } while (u8_char[0] != 'A');
    FLUSH_ESOS_COMM_IN_DATA();
    do
    {
    ESOS_TASK_WAIT_TICKS(500);
    ESOS_TASK_WAIT_ON_SEND_STRING("SA,1\n");
    if (IS_ESOS_COMM_GOT_IN_DATA())
    {
        ESOS_TASK_WAIT_ON_GET_STRING(u8_char);
    }
    u8_lastChar = u8_char[0];
    } while (u8_char[0] != 'A');
    FLUSH_ESOS_COMM_IN_DATA();
    do
    {
    ESOS_TASK_WAIT_TICKS(500);
    ESOS_TASK_WAIT_ON_SEND_STRING("SP,5555\n");
    if (IS_ESOS_COMM_GOT_IN_DATA())
    {
        ESOS_TASK_WAIT_ON_GET_STRING(u8_char);
    }
    u8_lastChar = u8_char[0];
    } while (u8_char[0] != 'A');
    FLUSH_ESOS_COMM_IN_DATA();
    do
    {
    ESOS_TASK_WAIT_TICKS(500);
    ESOS_TASK_WAIT_ON_SEND_STRING("---\n");
    if (IS_ESOS_COMM_GOT_IN_DATA())
    {
        ESOS_TASK_WAIT_ON_GET_STRING(u8_char);
    }
    u8_lastChar = u8_char[0];
    } while (u8_char[0] != 'E');
    FLUSH_ESOS_COMM_IN_DATA();
    ESOS_TASK_SIGNAL_AVAILABLE_OUT_COMM();
    ESOS_TASK_SIGNAL_AVAILABLE_IN_COMM();

//BEGIN ECHO PROGRAM
    while (TRUE)
    {
        u8_lastChar = u8_char[0];
        ESOS_TASK_WAIT_ON_AVAILABLE_IN_COMM();
        ESOS_TASK_WAIT_ON_GET_STRING(pu8_char);
        ESOS_TASK_SIGNAL_AVAILABLE_IN_COMM();
        ESOS_TASK_WAIT_ON_AVAILABLE_OUT_COMM();
        ESOS_TASK_WAIT_ON_SEND_STRING(u8_char);
        ESOS_TASK_WAIT_ON_SEND_STRING("\n");
        ESOS_TASK_SIGNAL_AVAILABLE_OUT_COMM();
    }
    ESOS_TASK_END();
}

void user_init(void)
{
	__esos_unsafe_PutString(HELLO_MSG);

	CONFIG_LED1();
	//CONFIG_LM60();
	//CONFIG_VREF();

	u16_minTemp = INIT_MIN_TEMP;
	u16_maxTemp = INIT_MAX_TEMP;
	u8_arrayIndex = 0;
	esos_SetUserFlag(BUFFER_INIT);

	configADC1_ManualCH0(ADC_CH0_POS_SAMPLEA_AN1, 31, 1);
        esos_RegisterTask(bt_COMM);
	esos_RegisterTask(heartbeat_LED);


	//esos_RegisterTask(readTemp);
	//esos_RegisterTask(commSerial);
}